package com.cangxuan.backend.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.cangxuan.backend.bean.Result;
import com.cangxuan.backend.dao.IGoodsDao;
import com.cangxuan.backend.dao.IUserDao;
import com.cangxuan.backend.entity.BlockChain;
import com.cangxuan.backend.entity.Goods;
import com.cangxuan.backend.entity.MarketGoods;
import com.cangxuan.backend.entity.User;
import com.cangxuan.backend.exception.ServiceException;
import com.cangxuan.backend.service.IGoodsService;
import com.cangxuan.backend.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class UserServiceImpl extends BaseServiceImpl implements IUserService {


    IUserDao userDao;

    @Autowired
    public void setUserDao(IUserDao userDao) {
        this.userDao = userDao;
    }

    RedisTemplate<String, Object> rateRedisTemplate;

    @Autowired
    public void setRateRedisTemplate(RedisTemplate<String, Object> rateRedisTemplate) {
        this.rateRedisTemplate = rateRedisTemplate;
    }

    @Override
    public User login(String mobile, String vCode, String deviceId, String registrationId) {
        // 1.校验短信验证码
        Object redisVCode = rateRedisTemplate.opsForValue().get("smsCode-" + mobile);


        if (redisVCode == null) {
            // 短信验证码已失效
            throw new ServiceException(402, "短信验证码已失效，请重新发送");
        }
        if (!vCode.equals(redisVCode.toString())) {
            // 验证码错误
            throw new ServiceException(401, "短信验证码错误");
        }
        log.info(mobile + "短信验证通过");
        // 2.去user表查询，如果没有，则insert，再查询。
        User user = userDao.selectByMobile(mobile);
        if (user == null) {
            log.info("当前手机号未注册，第一次登录，进行注册操作");
            user = new User(mobile, "未设置", "");
            user.setAvailable(true);    // 默认状态：可用
            user.setRegistrationId(registrationId);
            userDao.insert(user);
        } else {
            if (!user.isAvailable()) {
                throw new ServiceException(401, "账号已冻结，请联系客服");
            }
            userDao.updateRegistrationId(registrationId, user.getId());
        }
        // 以设备ID为键，保存对应的登录用户对象
        rateRedisTemplate.opsForValue().set("phone-deviceId-" + deviceId, user, 10, TimeUnit.DAYS);
        // 3.返回查询到的用户数据
        return user;
    }

    @Override
    public void changeNickname(String nickname) {
        int userId = getCurrentUser().getId();
        userDao.updateNickname(nickname, userId);
        // 重新从数据库中查询数据
        User user = userDao.selectById(userId);
        // 更新redis中的数据
        rateRedisTemplate.opsForValue().set("phone-deviceId-" + getCurrentDeviceId(), user, 10, TimeUnit.DAYS);
    }

    @Override
    public void changeTheSalesCalendar(boolean TheSalesCalendar) {

        int userId = getCurrentUser().getId();
        userDao.updateSubscribeToTheSalesCalendar(TheSalesCalendar, userId);
        // 重新从数据库中查询数据
        User user = userDao.selectById(userId);
        // 更新redis中的数据
        rateRedisTemplate.opsForValue().set("phone-deviceId-" + getCurrentDeviceId(), user, 10, TimeUnit.DAYS);
    }

    @Override
    public User getCurrentUser() {
        return super.getCurrentUser();
    }

    @Override

    public Object logout(String deviceId) {
        Object object = rateRedisTemplate.opsForValue().get("phone-deviceId-" + deviceId);
        return object;
    }

    @Override
    public Integer changeTransPassword(String transPassword, String oldTransPassword) {
        Integer a = 0;
        User user = userDao.selectById(getCurrentUser().getId());
        if (oldTransPassword == null && user.getTransPassword() == null) {
            a = userDao.updateTransPassword(transPassword, oldTransPassword, getCurrentUser().getId());
        } else if (oldTransPassword != null) {
            a = userDao.updateTransPassword(transPassword, oldTransPassword, getCurrentUser().getId());
        }
        if (a > 0) {
            user = userDao.selectById(getCurrentUser().getId());
            rateRedisTemplate.opsForValue().set("phone-deviceId-" + getCurrentDeviceId(), user, 10, TimeUnit.DAYS);
        }
        return a;
    }

    @Override
    public void addFollow(Integer goodsId) {
        Integer userId = getCurrentUser().getId();
        if (userDao.selectUserFollowGoods(userId, goodsId) == 0) {
            try {
                userDao.addUserFollowGoods(userId, goodsId);
            } catch (Exception e) {
                throw new ServiceException(401, "无效用户或商品ID");
            }
        } else {
            throw new ServiceException(201, "已关注该藏品");
        }
    }

    @Override
    public void cancelFollow(Integer goodsId) {
        Integer userId = getCurrentUser().getId();
        if (userDao.selectUserFollowGoods(userId, goodsId) == 1) {
            userDao.cancelUserFollowGoods(userId, goodsId);
        } else {
            throw new ServiceException(201, "还未关注该藏品");
        }
    }

    @Override
    public void viewFollow(int goodsId) {
        Integer userId = getCurrentUser().getId();
        int res = userDao.selectUserFollowGoods(userId, goodsId);
        if (res == 0) {
            throw new ServiceException(401, "还未关注该藏品");
        }
    }

    private IGoodsDao goodsDao;

    @Autowired
    public void setGoods(IGoodsDao goodsDao) {
        this.goodsDao = goodsDao;
    }

    @Override
    public List<MarketGoods> getFollowGoods(int pageIndex) {
        Integer userId = getCurrentUser().getId();

        List<MarketGoods> goodsList = userDao.userFollowGoods(userId, pageIndex);

        for (MarketGoods marketGoods : goodsList) {
            marketGoods.setCount(goodsDao.selectMarketOrderCount(marketGoods.getId()));
        }

        return goodsList;
    }

    public boolean updateDisplayMyGoods(byte displayMyGoods) {
        int i1 = userDao.updateDisplayMyGoods(displayMyGoods, getCurrentUser().getId());
        User user = userDao.selectById(getCurrentUser().getId());
        rateRedisTemplate.opsForValue().set("phone-deviceId-" + getCurrentDeviceId(), user, 10, TimeUnit.DAYS);
        return i1 > 0;
    }

    @Override
    public boolean updateDisplayMySellGoods(byte displayMySellGoods) {
        int i1 = userDao.updateDisplayMySellGoods(displayMySellGoods, getCurrentUser().getId());
        User user = userDao.selectById(getCurrentUser().getId());
        rateRedisTemplate.opsForValue().set("phone-deviceId-" + getCurrentDeviceId(), user, 10, TimeUnit.DAYS);
        return i1 > 0;
    }

    public void changeFacePath(String facePath) {
        int userId = getCurrentUser().getId();
        userDao.updateFacePath(facePath, userId);
        // 重新从数据库中查询数据
        User user = userDao.selectById(userId);
        // 更新redis中的数据
        rateRedisTemplate.opsForValue().set("phone-deviceId-" + getCurrentDeviceId(), user, 10, TimeUnit.DAYS);
    }

    @Override
    public void updateUserInformation(String realName, String IDCard, Integer userId) {
        userDao.updateUserRealNameAndIDCard(realName, IDCard, userId);
        // 重新从数据库中查询数据
        User user = userDao.selectById(userId);
        // 更新redis中的数据
        rateRedisTemplate.opsForValue().set("phone-deviceId-" + getCurrentDeviceId(), user, 10, TimeUnit.DAYS);

    }

    @Override
    public int updateRegistrationId(String registrationId) {
        return userDao.updateRegistrationId(registrationId, getCurrentUser().getId());
    }

    RestTemplate restTemplate;

    @Autowired
    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Override
    public Object getBlockChain(Long userId) {
        // 判断用户是否实名
        int isCertified = userDao.selectUserCertified(userId);
        System.out.println(isCertified);
        if (isCertified > 0) {
            String result;
            // 已经实名
            try {
                result = restTemplate.getForObject("http://CangXuanBlockchain/api/blockchain/getBlockChain/" + userId, String.class);
                System.out.println("---------" + result);
            } catch (Exception e) {
                return new Result(401, "获取区块链地址失败，请稍后再试...");
            }
            JSONObject resp = JSONObject.parseObject(result);
            if (resp.getInteger("status") == 200) {
                // 获取成功
                BlockChain blockChain = resp.getObject("value", BlockChain.class);
                String account = blockChain.getAccount();
                // 添加到数据库
                int count = userDao.updateBlockChain(userId, account);
                return new Result(200, account);
            } else {
                // 获取失败
                return new Result(401, "获取区块链地址失败，请稍后再试...");
            }
        }
        return new Result(401, "请完成实名认证后再获取区块链地址...");
    }
}
